package org.lemon.transport.context.service.queue.provider;

import lombok.extern.slf4j.Slf4j;
import org.lemon.transport.context.service.queue.QueueAdmin;
import org.lemon.transport.context.service.queue.QueueConsumer;
import org.lemon.transport.context.service.queue.QueueProducer;
import org.lemon.transport.context.data.queue.message.ProtoQueueMessage;
import org.lemon.transport.context.service.queue.rabbit.*;
import org.lemon.transport.context.service.queue.setting.QueueCoreSettings;
import org.lemon.transport.context.service.queue.setting.QueueRuleEngineSettings;
import org.lemon.transport.context.service.queue.setting.QueueTransportApiSettings;
import org.lemon.transport.context.service.queue.setting.QueueTransportNotificationSettings;
import org.server.transport.gen.TransportProto;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RabbitMqCoreQueueFactory {

    private final RabbitMqSettings rabbitMqSettings;

    private final QueueCoreSettings coreSettings;
    private final QueueRuleEngineSettings ruleEngineSettings;
    private final QueueTransportApiSettings transportApiSettings;
    private final QueueTransportNotificationSettings transportNotificationSettings;

    private final QueueAdmin coreAdmin;
    private final QueueAdmin ruleEngineAdmin;
    private final QueueAdmin transportApiAdmin;
    private final QueueAdmin notificationAdmin;

    public RabbitMqCoreQueueFactory(RabbitMqSettings rabbitMqSettings,
                                    QueueCoreSettings coreSettings,
                                    QueueRuleEngineSettings ruleEngineSettings,
                                    QueueTransportApiSettings transportApiSettings,
                                    QueueTransportNotificationSettings transportNotificationSettings,
                                    RabbitMqQueueArguments queueArguments) {
        this.rabbitMqSettings = rabbitMqSettings;
        this.coreSettings = coreSettings;
        this.ruleEngineSettings = ruleEngineSettings;
        this.transportApiSettings = transportApiSettings;
        this.transportNotificationSettings = transportNotificationSettings;

        this.coreAdmin = new RabbitMqAdmin(rabbitMqSettings, queueArguments.getCoreArgs());
        this.ruleEngineAdmin = new RabbitMqAdmin(rabbitMqSettings, queueArguments.getRuleEngineArgs());
        this.transportApiAdmin = new RabbitMqAdmin(rabbitMqSettings, queueArguments.getTransportApiArgs());
        this.notificationAdmin = new RabbitMqAdmin(rabbitMqSettings, queueArguments.getNotificationsArgs());
    }

    /**
     * 创建规则引擎消息生产者
     */
    public QueueProducer<ProtoQueueMessage<TransportProto.ToRuleEngineMsg>> createRuleEngineMessageProducer() {

        return new RabbitMqProducerTemplate<>(ruleEngineAdmin, rabbitMqSettings, ruleEngineSettings.getTopic());
    }

    /**
     * 创建应用消息消费者
     */
    public QueueConsumer<ProtoQueueMessage<TransportProto.ToCoreMsg>> createCoreMessageConsumer() {

        return new RabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getTopic(),
                msg -> new ProtoQueueMessage<>(msg.getKey(), TransportProto.ToCoreMsg.parseFrom(msg.getData()), msg.getHeaders()));
    }

    /**
     * 创建规则引擎通知消息消费者
     */
    public QueueConsumer<ProtoQueueMessage<TransportProto.ToCoreMsg>> createRuleEngineNotificationsMessageProducer() {

        return new RabbitMqConsumerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getTopic(),
                msg -> new ProtoQueueMessage<>(msg.getKey(), TransportProto.ToCoreMsg.parseFrom(msg.getData()), msg.getHeaders()));
    }

    /**
     * 创建应用消息生产者
     */
    public QueueProducer<ProtoQueueMessage<TransportProto.ToCoreMsg>> createCoreMessageProducer() {

        return new RabbitMqProducerTemplate<>(coreAdmin, rabbitMqSettings, coreSettings.getTopic());
    }
}
